"""
Folder Management API Router
文件夹管理API路由
"""

import uuid
from typing import Optional, List, Dict, Any

from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_, or_, desc

from ..core.database import get_db
from ..core.logging import error_logger
from ..core.exceptions import (
    FolderNotFoundError,
    FolderAccessDeniedError,
    FolderNameConflictError,
    ValidationError,
)
from ..models.user import User
from ..models.folder import Folder, FolderType, FolderVisibility
from ..models.generated_content import GeneratedContent
from ..services.folder_management_service import FolderManagementService
from .auth import get_current_user

router = APIRouter()


@router.post("/")
async def create_folder(
    name: str,
    parent_id: Optional[str] = Query(None, description="父文件夹ID，留空则创建根文件夹"),
    description: Optional[str] = Query(None, description="文件夹描述"),
    folder_type: str = Query("user", description="文件夹类型: user, system, shared, archive, trash"),
    visibility: str = Query("private", description="可见性: private, public, shared"),
    color: Optional[str] = Query(None, description="文件夹颜色 (#RRGGBB)"),
    icon: Optional[str] = Query(None, description="图标标识"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """创建文件夹"""
    try:
        folder_service = FolderManagementService(db)
        
        # 验证文件夹名称
        if not name or len(name.strip()) == 0:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="文件夹名称不能为空"
            )
        
        # 验证用户权限（只有管理员可以创建系统文件夹）
        if folder_type == "system" and not current_user.is_admin:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="无权限创建系统文件夹"
            )
        
        # 如果指定了父文件夹，验证其存在且属于用户
        parent_folder_id = None
        if parent_id:
            parent_result = await db.execute(
                select(Folder).where(
                    and_(
                        Folder.id == uuid.UUID(parent_id),
                        Folder.user_id == current_user.id,
                        Folder.is_deleted == False
                    )
                )
            )
            parent_folder = parent_result.scalar_one_or_none()
            if not parent_folder:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="父文件夹不存在或无权限访问"
                )
            parent_folder_id = parent_folder.id
        
        # 创建文件夹
        folder = await folder_service.create_folder(
            user=current_user,
            name=name.strip(),
            parent_id=parent_folder_id,
            description=description,
            folder_type=folder_type,
            visibility=visibility,
            color=color,
            icon=icon
        )
        
        return {
            "success": True,
            "data": {
                "id": str(folder.id),
                "name": folder.name,
                "description": folder.description,
                "path": folder.path,
                "parent_id": str(folder.parent_id) if folder.parent_id else None,
                "folder_type": folder.folder_type,
                "visibility": folder.visibility,
                "color": folder.color,
                "icon": folder.icon,
                "content_count": folder.content_count,
                "subfolder_count": folder.subfolder_count,
                "created_at": folder.created_at.isoformat(),
            },
            "message": "文件夹创建成功"
        }
        
    except FolderNameConflictError as e:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=str(e)
        )
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "create_folder",
                "user_id": str(current_user.id),
                "name": name,
                "parent_id": parent_id
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件夹创建失败，请稍后重试"
        )


@router.get("/tree")
async def get_folder_tree(
    include_system: bool = Query(False, description="是否包含系统文件夹"),
    include_content_count: bool = Query(True, description="是否包含内容数量"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取文件夹树形结构"""
    try:
        folder_service = FolderManagementService(db)
        
        # 获取用户的文件夹树
        folder_tree = await folder_service.get_user_folder_tree(
            user=current_user,
            include_system=include_system
        )
        
        # 格式化树形数据
        def format_folder_node(folder):
            node = {
                "id": str(folder.id),
                "name": folder.name,
                "path": folder.path,
                "folder_type": folder.folder_type,
                "visibility": folder.visibility,
                "color": folder.color,
                "icon": folder.icon,
                "is_system": folder.is_system,
                "is_locked": folder.is_locked,
                "can_delete": folder.can_delete,
                "can_rename": folder.can_rename,
                "created_at": folder.created_at.isoformat(),
            }
            
            if include_content_count:
                node.update({
                    "content_count": folder.content_count,
                    "total_content_count": folder.total_content_count,
                    "subfolder_count": folder.subfolder_count,
                })
            
            # 递归添加子文件夹
            if folder.children:
                node["children"] = [format_folder_node(child) for child in folder.children]
            else:
                node["children"] = []
            
            return node
        
        # 获取根文件夹
        root_folders = [folder for folder in folder_tree if folder.is_root]
        
        return {
            "success": True,
            "data": [format_folder_node(folder) for folder in root_folders]
        }
        
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_folder_tree",
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取文件夹树失败，请稍后重试"
        )


@router.get("/{folder_id}")
async def get_folder(
    folder_id: str,
    include_contents: bool = Query(False, description="是否包含内容列表"),
    include_subfolders: bool = Query(True, description="是否包含子文件夹"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """获取文件夹详情"""
    try:
        folder_service = FolderManagementService(db)
        
        # 获取文件夹
        folder = await folder_service.get_folder(
            uuid.UUID(folder_id),
            current_user
        )
        
        if not folder:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="文件夹不存在或无权限访问"
            )
        
        # 获取面包屑导航
        breadcrumb = folder.get_breadcrumb()
        
        result = {
            "success": True,
            "data": {
                "id": str(folder.id),
                "name": folder.name,
                "description": folder.description,
                "path": folder.path,
                "parent_id": str(folder.parent_id) if folder.parent_id else None,
                "folder_type": folder.folder_type,
                "visibility": folder.visibility,
                "color": folder.color,
                "icon": folder.icon,
                "content_count": folder.content_count,
                "total_content_count": folder.total_content_count,
                "subfolder_count": folder.subfolder_count,
                "is_system": folder.is_system,
                "is_locked": folder.is_locked,
                "can_delete": folder.can_delete,
                "can_rename": folder.can_rename,
                "is_archived": folder.is_archived,
                "is_deleted": folder.is_deleted,
                "created_at": folder.created_at.isoformat(),
                "updated_at": folder.updated_at.isoformat(),
                "breadcrumb": breadcrumb,
            }
        }
        
        # 包含内容列表
        if include_contents:
            content_result = await db.execute(
                select(GeneratedContent).where(
                    and_(
                        GeneratedContent.folder_id == folder.id,
                        GeneratedContent.is_deleted == False
                    )
                ).order_by(GeneratedContent.created_at.desc())
            )
            contents = content_result.scalars().all()
            
            result["data"]["contents"] = [
                {
                    "id": str(content.id),
                    "title": content.title,
                    "content_type": content.content_type,
                    "format": content.format,
                    "status": content.status,
                    "thumbnail_url": content.thumbnail_url,
                    "file_size_readable": content.file_size_readable,
                    "is_favorite": content.is_favorite,
                    "created_at": content.created_at.isoformat(),
                }
                for content in contents
            ]
        
        # 包含子文件夹
        if include_subfolders:
            subfolder_result = await db.execute(
                select(Folder).where(
                    and_(
                        Folder.parent_id == folder.id,
                        Folder.is_deleted == False
                    )
                ).order_by(Folder.name)
            )
            subfolders = subfolder_result.scalars().all()
            
            result["data"]["subfolders"] = [
                {
                    "id": str(subfolder.id),
                    "name": subfolder.name,
                    "path": subfolder.path,
                    "content_count": subfolder.content_count,
                    "subfolder_count": subfolder.subfolder_count,
                    "created_at": subfolder.created_at.isoformat(),
                }
                for subfolder in subfolders
            ]
        
        return result
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "get_folder",
                "folder_id": folder_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="获取文件夹详情失败，请稍后重试"
        )


@router.put("/{folder_id}")
async def update_folder(
    folder_id: str,
    name: Optional[str] = Query(None, description="新名称"),
    description: Optional[str] = Query(None, description="新描述"),
    color: Optional[str] = Query(None, description="新颜色"),
    icon: Optional[str] = Query(None, description="新图标"),
    visibility: Optional[str] = Query(None, description="新可见性"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """更新文件夹信息"""
    try:
        folder_service = FolderManagementService(db)
        
        # 准备更新数据
        update_data = {}
        if name is not None:
            if not name or len(name.strip()) == 0:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="文件夹名称不能为空"
                )
            update_data["name"] = name.strip()
        if description is not None:
            update_data["description"] = description
        if color is not None:
            update_data["color"] = color
        if icon is not None:
            update_data["icon"] = icon
        if visibility is not None:
            update_data["visibility"] = visibility
        
        # 更新文件夹
        success = await folder_service.update_folder(
            uuid.UUID(folder_id),
            current_user,
            update_data
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="文件夹不存在或无权限更新"
            )
        
        return {
            "success": True,
            "message": "文件夹更新成功"
        }
        
    except FolderNameConflictError as e:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail=str(e)
        )
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "update_folder",
                "folder_id": folder_id,
                "user_id": str(current_user.id),
                "update_data": update_data
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件夹更新失败，请稍后重试"
        )


@router.delete("/{folder_id}")
async def delete_folder(
    folder_id: str,
    force: bool = Query(False, description="是否强制删除（包含内容）"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """删除文件夹"""
    try:
        folder_service = FolderManagementService(db)
        
        # 删除文件夹
        success = await folder_service.delete_folder(
            uuid.UUID(folder_id),
            current_user,
            force_delete=force
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="文件夹不存在或无权限删除"
            )
        
        return {
            "success": True,
            "message": "文件夹删除成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "delete_folder",
                "folder_id": folder_id,
                "user_id": str(current_user.id),
                "force": force
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件夹删除失败，请稍后重试"
        )


@router.post("/{folder_id}/move")
async def move_folder(
    folder_id: str,
    target_parent_id: Optional[str] = Query(None, description="目标父文件夹ID，留空则移动到根目录"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """移动文件夹"""
    try:
        folder_service = FolderManagementService(db)
        
        # 准备目标父文件夹ID
        target_parent_uuid = None
        if target_parent_id:
            target_parent_uuid = uuid.UUID(target_parent_id)
        
        # 移动文件夹
        success = await folder_service.move_folder(
            uuid.UUID(folder_id),
            current_user,
            target_parent_id=target_parent_uuid
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="文件夹不存在或无权限移动"
            )
        
        return {
            "success": True,
            "message": "文件夹移动成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "move_folder",
                "folder_id": folder_id,
                "target_parent_id": target_parent_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件夹移动失败，请稍后重试"
        )


@router.post("/{source_folder_id}/copy/{target_folder_id}")
async def copy_folder_contents(
    source_folder_id: str,
    target_folder_id: str,
    include_subfolders: bool = Query(True, description="是否包含子文件夹内容"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """复制文件夹内容到另一个文件夹"""
    try:
        folder_service = FolderManagementService(db)
        
        # 复制文件夹内容
        copied_count = await folder_service.copy_folder_contents(
            uuid.UUID(source_folder_id),
            uuid.UUID(target_folder_id),
            current_user,
            include_subfolders=include_subfolders
        )
        
        return {
            "success": True,
            "data": {
                "copied_count": copied_count
            },
            "message": f"成功复制 {copied_count} 个内容项"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "copy_folder_contents",
                "source_folder_id": source_folder_id,
                "target_folder_id": target_folder_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="复制文件夹内容失败，请稍后重试"
        )


@router.post("/{folder_id}/archive")
async def archive_folder(
    folder_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """归档文件夹"""
    try:
        folder_service = FolderManagementService(db)
        
        # 归档文件夹
        success = await folder_service.archive_folder(
            uuid.UUID(folder_id),
            current_user
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="文件夹不存在或无权限归档"
            )
        
        return {
            "success": True,
            "message": "文件夹归档成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "archive_folder",
                "folder_id": folder_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件夹归档失败，请稍后重试"
        )


@router.post("/{folder_id}/restore")
async def restore_folder(
    folder_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    """恢复已归档的文件夹"""
    try:
        folder_service = FolderManagementService(db)
        
        # 恢复文件夹
        success = await folder_service.restore_folder(
            uuid.UUID(folder_id),
            current_user
        )
        
        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="文件夹不存在或无权限恢复"
            )
        
        return {
            "success": True,
            "message": "文件夹恢复成功"
        }
        
    except HTTPException:
        raise
    except Exception as e:
        error_logger.log_error(
            e, {
                "operation": "restore_folder",
                "folder_id": folder_id,
                "user_id": str(current_user.id)
            }
        )
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件夹恢复失败，请稍后重试"
        )


# 导出路由
__all__ = ["router"]